#region File information

/**
 * File: Grid.cs
 * Date: 08-03-2008
 * Auth: Jan-Jaap Severs
 * 
 * Desc: Component that renders a grid at world origin height, with user-definable dimensions.
 */

#endregion

#region Using statements

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

#endregion

namespace Gremlin.Components
{
    public class Grid : Microsoft.Xna.Framework.DrawableGameComponent
    {
        VertexPositionColor[] _gridPoints;
        BasicEffect _effect;

        private int _gridSize = 16;
        private int _gridScale = 32;

        public Grid(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
        }

        public override void Initialize()
        {
            base.Initialize();

            _gridPoints = new VertexPositionColor[(_gridSize + 1) * 4];

            float startpoint = (_gridSize * _gridScale) / 2;

            for (int count = 0; count < _gridSize + 1; count++)
            {
                float position = -startpoint + (count * _gridScale);

                _gridPoints[4 * count] = new VertexPositionColor(new Vector3(startpoint, 0, position), Color.Yellow);
                _gridPoints[4 * count + 1] = new VertexPositionColor(new Vector3(-1 * startpoint, 0, position), Color.Yellow);
                _gridPoints[4 * count + 2] = new VertexPositionColor(new Vector3(position, 0, startpoint), Color.Yellow);
                _gridPoints[4 * count + 3] = new VertexPositionColor(new Vector3(position, 0, -1 * startpoint), Color.Yellow);
            }

            // Setup default effect
            IGraphicsDeviceService graphicsservice = (IGraphicsDeviceService)Game.Services.GetService(typeof(IGraphicsDeviceService));
            _effect = new BasicEffect(graphicsservice.GraphicsDevice, null);
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            Camera cam = ((CameraProvider)Game.Services.GetService(typeof(ICameraService))).Camera;

            if (cam == null)
                return;

            _effect.View = cam.ViewMatrix;
            _effect.Projection = cam.ProjMatrix;

            IGraphicsDeviceService graphicsservice = (IGraphicsDeviceService)Game.Services.GetService(typeof(IGraphicsDeviceService));
            GraphicsDevice graphicsdevice = graphicsservice.GraphicsDevice;

            using (VertexDeclaration vertexdeclaration = new VertexDeclaration(graphicsdevice, VertexPositionColor.VertexElements))
            {
                graphicsdevice.VertexDeclaration = vertexdeclaration;
                graphicsdevice.RenderState.CullMode = CullMode.None;

                _effect.Alpha = 1.0f;
                _effect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
                _effect.AmbientLightColor = new Vector3(0.5f, 0.5f, 0.5f);
                _effect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f);
                _effect.SpecularPower = 5.0f;
                _effect.AmbientLightColor = new Vector3(0.75f, 0.75f, 0.75f);

                _effect.Begin();
                foreach (EffectPass pass in _effect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    graphicsdevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, _gridPoints, 0, (_gridSize + 1) * 2);
                    pass.End();
                }
                _effect.End();
            }
        }

        #region Accessors & actuators

        public int GridSize
        {
            get { return _gridSize; }
            set { _gridSize = value; }
        }

        public int GridScale
        {
            get { return _gridScale; }
            set { _gridScale = value; }
        }

        #endregion
    }
}
